package cn.szsys.integration.util;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.szsys.integration.ex.MissingRequireParamException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.groups.Default;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Ryan
 * @since 2025-05-08
 **/
public class CustomValidationUtil {
    public static final Validator VALIDATOR;

    static {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        // 根据validatorFactory拿到一个Validator
        VALIDATOR = validatorFactory.getValidator();
    }

    /**
     * 使用validate校验参数必填
     *
     * @param t      参数
     * @param tClass group class
     * @author Ryan
     */
    @SuppressWarnings("all")
    public static <T> void valid(T t, Class<?>... tClass) {
        if (t instanceof Collection) {
            Collection collection = (Collection) t;
            Iterator iterator = collection.iterator();
            if (iterator.hasNext()) {
                Object next = iterator.next();
                check(next, tClass);
            }
        }
        check(t, tClass);
    }

    /**
     * 使用Validator执行校验
     *
     * @param t      泛型
     * @param tClass 分组校验的class
     * @author Ryan
     */
    private static <T> void check(T t, Class<?>... tClass) {
        Set<ConstraintViolation<Object>> result;
        if (ArrayUtil.isEmpty(tClass)) {
            result = VALIDATOR.validate(t, Default.class);
        } else {
            Class<?>[] append = ArrayUtil.append(tClass, Default.class);
            result = VALIDATOR.validate(t, append);
        }
        if (CollUtil.isNotEmpty(result)) {
            // 对结果进行遍历输出
            String s = result.stream()
                    .map(ConstraintViolation::getMessage)
                    .reduce((m1, m2) -> String.join("", m1, m2))
                    .orElse("");
            throw new MissingRequireParamException(s);
        }
    }

}
